package com.xingfly.web.api;

import com.xingfly.authentication.annotation.Authorization;
import com.xingfly.authentication.annotation.Me;
import com.xingfly.constant.ApiConstant;
import com.xingfly.constant.ErrorConstant;
import com.xingfly.constant.HttpStatus;
import com.xingfly.constant.NotificationStatus;
import com.xingfly.error.TipException;
import com.xingfly.model.*;
import com.xingfly.model.vo.*;
import com.xingfly.service.*;
import com.xingfly.util.FeedUtils;
import com.xingfly.web.model.ResponseModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by SuperS on 22/05/2017.
 *
 * @author SuperS
 */
@RestController
@RequestMapping("/api/me")
@Api(value = "me", description = "登录后的相关操作")
public class MeController {
    @Autowired
    private FeedService feedService;
    @Autowired
    private PostService postService;
    @Autowired
    private CountService countService;
    @Autowired
    private ImageService imageService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private FriendService friendService;
    @Autowired
    private NotificationService notificationService;


    @ApiOperation(value = "获取我的好友动态", notes = "验证通过后获取好友的动态(时间、ID排列)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true),
            @ApiImplicitParam(name = "page", value = "页", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "单页显示数量", dataType = "Integer", paramType = "query")
    })
    @Authorization
    @GetMapping("feeds")
    public ResponseModel feeds(@ApiIgnore @Me User me,
                               @RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
                               @RequestParam(name = "size", required = false, defaultValue = "10") Integer size) {
        //查询当前用户作为粉丝的所有事件、也就是查我关注的用户的动态。
        List<Event> events = feedService.findEventsByFansId(me.getId(), new PageRequest(page, size, new Sort(Sort.Direction.DESC, "createTime", "id"))).getContent();
        //FeedUtils.assemblingFeedVO 负责组装 FeedVO
        List<FeedVO> feedVOS = FeedUtils.assemblingFeedVO(events,
                postService, countService, imageService, commentService);
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(feedVOS).build();
    }

    @ApiOperation(value = "获取我的粉丝", notes = "验证通过后获取我的粉丝(ID排列)")
    @GetMapping("fans")
    @Authorization
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true),
            @ApiImplicitParam(name = "page", value = "页", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "单页显示数量", dataType = "Integer", paramType = "query")
    })
    public ResponseModel fans(@ApiIgnore @Me User me,
                              @RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
                              @RequestParam(name = "size", required = false, defaultValue = "10") Integer size) {
        List<Friend> friends = friendService.findUserFansByUserId(me.getId(), new PageRequest(page, size)).getContent();
        List<FansVO> fansVOS = new ArrayList<>();
        for (Friend friend : friends) {
            FansVO fansVO = new FansVO();
            User u = friend.getFans();
            fansVO.setUserVO(UserVO.toVO(u));
            fansVO.setId(friend.getId());
            fansVOS.add(fansVO);
        }
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(fansVOS).build();
    }

    @ApiOperation(value = "获取我关注的人", notes = "验证通过后获取我关注的人(ID排列)")
    @GetMapping("starts")
    @Authorization
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true),
            @ApiImplicitParam(name = "page", value = "页", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "单页显示数量", dataType = "Integer", paramType = "query")
    })
    public ResponseModel starts(@ApiIgnore @Me User me,
                                @RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
                                @RequestParam(name = "size", required = false, defaultValue = "10") Integer size) {
        List<Friend> friends = friendService.findUserStartsByUserId(me.getId(), new PageRequest(page, size)).getContent();
        List<StarVO> startVOS = new ArrayList<>();
        for (Friend friend : friends) {
            StarVO startVO = new StarVO();
            User u = friend.getStart();
            startVO.setUserVO(UserVO.toVO(u));
            startVO.setId(friend.getId());
            startVOS.add(startVO);
        }
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(startVOS).build();
    }

    @ApiOperation(value = "获取我的粉丝数", notes = "验证通过后获取我的粉丝数量(ID排列)")
    @Authorization
    @GetMapping("fans/count")
    @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true)
    public ResponseModel fansCount(@ApiIgnore @Me User me) {
        Long fansCount = friendService.countFans(me.getId());
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(fansCount).build();
    }

    @ApiOperation(value = "获取我关注的人数", notes = "验证通过后获取我关注的人数量(ID排列)")
    @Authorization
    @GetMapping("starts/count")
    @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true)
    public ResponseModel startsCount(@ApiIgnore @Me User me) {
        Long fansCount = friendService.countStats(me.getId());
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(fansCount).build();
    }

    @GetMapping("posts")
    @Authorization
    @ApiOperation(value = "获取我的posts", notes = "验证通过后获取我的posts(时间排列)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "单页显示数量", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true)
    })
    public ResponseModel posts(@ApiIgnore @Me User me,
                               @RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
                               @RequestParam(name = "size", required = false, defaultValue = "10") Integer size) {
        List<Post> posts = postService.findPostsByUserId(me.getId(), new PageRequest(page, size, new Sort(Sort.Direction.DESC, "createTime"))).getContent();
        List<PostVO> postVOS = new ArrayList<>();
        for (Post p : posts) {
            postVOS.add(PostVO.toVO(p));
        }
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(postVOS).build();
    }

    @GetMapping("posts/count")
    @Authorization
    @ApiOperation(value = "获取我的post数量", notes = "验证通过后获取我的posts数量")
    @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true)
    public ResponseModel postsCount(@ApiIgnore @Me User user) {
        Long postsCount = postService.countPostsByUserId(user.getId());
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(postsCount).build();
    }

    @GetMapping("notifications")
    @Authorization
    @ApiOperation(value = "获取我的notifications", notes = "验证通过后获取notificaitons(时间排列)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "单页显示数量", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "提醒状态（0未读、1已读、2全部）", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true)
    })
    public ResponseModel notifications(@ApiIgnore @Me User me,
                                       @RequestParam(name = "status", required = false, defaultValue = "2") Integer status,
                                       @RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
                                       @RequestParam(name = "size", required = false, defaultValue = "10") Integer size) {
        List<Notification> notifications = null;
        List<NotificationVO> notificationVOS = new ArrayList<>();
        switch (status) {
            //查询未读提醒
            case 0:
                notifications = notificationService.findNotificationsByUserIdAndStatus(me.getId(), NotificationStatus.NOT_READ, new PageRequest(page, size, new Sort(Sort.Direction.DESC, "createTime"))).getContent();
                break;
            //查询已读提醒
            case 1:
                notifications = notificationService.findNotificationsByUserIdAndStatus(me.getId(), NotificationStatus.IS_READ, new PageRequest(page, size, new Sort(Sort.Direction.DESC, "createTime"))).getContent();
                break;
            //查询所有提醒
            default:
                notifications = notificationService.findNotificationsByUserId(me.getId(), new PageRequest(page, size, new Sort(Sort.Direction.DESC, "createTime"))).getContent();
                break;
        }
        if (notifications != null) {
            for (Notification n : notifications) {
                notificationVOS.add(NotificationVO.toVO(n));
            }
        }
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(notificationVOS).build();
    }

    @GetMapping("notifications/count")
    @Authorization
    @ApiOperation(value = "获取我的提醒数量", notes = "验证通过后获取我的提醒数量(默认未读 0:未读  1:已读 *:所有)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true),
            @ApiImplicitParam(name = "status", value = "提醒状态", dataType = "Integer", paramType = "query")
    })
    public ResponseModel notificationsCount(@ApiIgnore @Me User me,
                                            @RequestParam(value = "status", required = false, defaultValue = "0") Integer status) {
        Long count = null;
        switch (status) {
            case 0:
                count = notificationService.countNotificationsByUserId(me.getId(), NotificationStatus.NOT_READ);
                break;
            case 1:
                count = notificationService.countNotificationsByUserId(me.getId(), NotificationStatus.IS_READ);
                break;
            default:
                count = notificationService.countNotificationsByUserId(me.getId());
                break;
        }
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(count).build();
    }

    @PutMapping("notifications/{id}")
    @Authorization
    @ApiOperation(value = "设置消息为已读并", notes = "验证通过后设置为已读")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = ApiConstant.AUTHORIZATION, paramType = "header", dataType = "String", required = true),
            @ApiImplicitParam(name = "id", required = true, dataType = "Long", paramType = "path")

    })
    public ResponseModel deleteNotification(@PathVariable("id") Long id, @ApiIgnore @Me User me) throws TipException {
        Notification n = notificationService.findById(id);
        if (n == null) {
            throw new TipException(ErrorConstant.ERROR_MSG_NOTIFICATION_NOT_FOUND, ErrorConstant.ERROR_CODE_NOTIFICATION_NOT_FOUND);
        }
        if (!n.getReceiver().getId().equals(me.getId())) {
            throw new TipException(ErrorConstant.ERROR_MSG_USER_NOT_MATCH, ErrorConstant.ERROR_CODE_USER_NOT_MATCH);
        }
        n.setStatus(NotificationStatus.IS_READ);
        Notification saved = notificationService.save(n);
        return ResponseModel.builder().message(HttpStatus.STATUS_INFO_ACCEPTED).data(HttpStatus.STATUS_CODE_ACCEPTED).data(NotificationVO.toVO(saved)).build();
    }
}
